#ifndef __DSTH_CHANNEL_H__
#define __DSTH_CHANNEL_H__

#include "AcfDelegate.h"
#include "Timestamp.h"
using namespace Acf;

//4800: 'const int' : forcing value to bool 'true' or 'false'
#ifdef _MSC_VER
#pragma warning(disable:4800)
#endif

namespace dsth {

class Socket;
class EventLoop;
class Channel
{
public:
    static const int kNoneEvent;
    static const int kReadEvent;
    static const int kWriteEvent;
    static const int kErrorEvent;

    typedef Delegate<void (Timestamp)> ReadHandler;
    typedef Delegate<void ()> WriteHandler;
    typedef Delegate<void ()> ErrorHandler;
    
    Channel(int fd, EventLoop* loop);
    ~Channel(void);
    void SetReadHandler(const ReadHandler& handler) { read_handler_ = handler; }
    void SetWriteHandler(const WriteHandler& handler) { write_handler_ = handler; }
    void SetErrorHandler(const ErrorHandler& handler) { error_handler_ = handler; }

    void EnableReading();
    void EnableWriting();
    void DisableReading();
    void DisableWriting();
    void DisableAllEvent();
    void HandleEvent(Timestamp recv_time);
    int GetSocketFd();

    bool IsWriting() { return event_ & kWriteEvent; }
    bool IsReading() { return event_ & kReadEvent; }
    bool IsNoneEvent() { return event_ == kNoneEvent; }
    int GetEvent() const { return event_; }
    void SetRevent(int event) { revent_ = event; }
    EventLoop* GetOwnerLoop() { return loop_ptr_; }

    // for epoll
    enum STATUS { E_NEW, E_ADDED, E_DELED };
    void SetStatus(STATUS status) { status_ = status; }
    STATUS GetStatus() { return status_; }
private:
    // Can't invoke copy constructor or assignment operator
    Channel(const Channel&);
    void operator=(const Channel&);

    // delegaters
    ReadHandler read_handler_;
    WriteHandler write_handler_;
    ErrorHandler error_handler_;    
    
    int fd_;
    EventLoop* loop_ptr_;
    int event_;
    int revent_;
    STATUS status_; // for epoll
};

} // namespace
#endif // __DSTH_CHANNEL_H__
